package pers.vic.basics.sort;

import java.util.Arrays;

/**
 * @author Vic.xu
 * @description:快速排序-高级排序 分治算法
 * @date: 2020/10/26 0026 10:15
 */
public class QuickSort {
    /*
    快速排序的基本思路：
    1. 以最左侧数为基准数
    2. 分别从两边开始检索
       2.1 从右边开始检索，若遇到比基准数小，则停止
       2.2 从左边开始检索，如果遇到比基准数大，则停止
       2.3 交换检索到的左右两个数，然后继续检索，直到二者相遇，然后交换校准数和相遇位置的数
   至此，第一轮排序结束，此时，基准数左边均比基准数小，基准数右边均比基准数大

     再把左右区间重复上述步骤

     */


    public static void sort(int[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    protected static void sort(int[] arr, int left, int right) {
        if (left >= right) {
            return;
        }
        //从左侧开始检索的下标
        int i = left;
        //从右侧开始检索的下标
        int j = right;
        //基准数
        int base = arr[left];
        //两者不相遇则不停止检索
        while (i != j) {
            //先从右侧开始检索,直到找到右侧小于基准的
            while (arr[j] >= base && j > i) {
                j--;
            }
            //再从左侧开始检索，直到找到左侧比基准数大的
            while (arr[i] <= base && j > i) {
                i++;
            }
            //交换两者的位置
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        //两者相遇后，交换基准数和相遇位置，然后对两个区间重复上述操作
        arr[left] = arr[i];
        arr[i] = base;
        sort(arr, left, i - 1);
        sort(arr, i + 1, right);
    }


    public static void main(String[] args) {
        int[] arr = {6, 7, 9, 8, 0, 4, 1, 3, 2};
        System.out.println(Arrays.toString(arr));
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}
